1. Field of the Invention
This invention relates to the field of computer software optimization. More particularly, the present invention relates to a method for run-time tracking of object references in computer code.
2. History of the Prior Art
Computer programs are generally created as source code. The source code is then compiled into object code for execution. Programs generally exist as compiled object code in computer systems. The compiled code is usually designed to operate on only one particular operating system or on only one particular computer processor architecture. In order to use a certain program on several different computer architectures, the original source code must be compiled into object code for each different operating system and each different computer processor architecture.
In recent years, the popularization of the World Wide Web has created a problem for software developers trying to build software for networked consumer devices. Millions of people around the world are surfing the Internet and browsing web pages with their computers. However, not all of the computers are of the same type. For instance, a person may be using a Macintosh, a PC, or a UNIX machine. Computer programs need to be designed to support multiple host architectures and to allow secure delivery of its software components. As a result, Sun Microsystems, Inc., introduced Java, a general purpose concurrent object oriented programming language. Java was designed such that Java code could survive transport across networks, operate on any client, and assure the client that it was safe to run.
Java is a strongly typed programming language. A program is created by compiling source code written in Java's well defined format into Java bytecodes. Compilation normally consists of translating Java programs into a machine independent bytecode representation. Bytecodes are executed by a runtime interpreter residing on the client computer. Run time activities include loading and linking the classes needed to execute a program, optional machine code generation and dynamic optimization of the program, and actual program execution.
Java bytecodes are designed to execute on a Java Virtual Machine. The Java Virtual Machine is an abstract computing machine that has an instruction set and uses various memory areas. A Java Virtual Machine is not an actual hardware platform, but rather a low level software emulator that can be implemented on many different computer processor architectures and under many different operating systems. The Java Virtual Machine reads and interprets each bytecode so that the instructions may be executed by the native microprocessor. Hence a compiled Java bytecode is capable of functioning on any platform that has a Java Virtual Machine implementation available. However, bytecode interpretation detracts from processor performance since the microprocessor has to spend some of its processing time interpreting bytecode instructions. "Just in Time" (JIT) compilers were introduced to improve the performance of Java Virtual Machines. A JIT compiler translates Java bytecodes into the processor's native machine code during runtime. The processor then executes the compiled native code like any other native program. Such compiled Java programs execute much faster than Java programs that are executed using a Java interpreter.
Java was derived from the C++ programming language. Java includes some other important features from garbage collected languages (e.g., Smalltalk and LISP)--including automatic memory storage management. Garbage collected languages, such as Java, allow the system (garbage collector) to take over the burden of memory management from the programmer. When a program runs low on heap space, the garbage collector (GC) determines the set of objects that program may still access. This set of objects are known as live objects. The space used by objects that will no longer be accessed ("dead objects") is freed by the garbage collector for future use.
There are many algorithms for performing garbage collection. One type of garbage collection is called conservative garbage collection. In conservative garbage collection, the garbage collector searches for a set of live objects, but does not move the objects it finds. The set of live objects (root set) includes live objects that exist in global variables, in registers, and on the runtime stack. The GC simply marks the objects as live without checking whether the objects are references. Another type of garbage collection is precise garbage collection. In precise garbage collection, the root set must all contain reference values or be initialized, or else memory errors will result. This is because precise garbage collection compacts the memory space by moving all the objects it finds to another memory region. The values in the root set must contain reference values since the garbage collector copies and moves the objects pointed to by references. If a value is mistakenly considered a reference value when it is not, a wrong piece of data will be moved and program errors may occur.